﻿using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using YonYou.U8.IN.Forms;
using YonYou.U8.IN.Framework.Actions;
using YonYou.U8.IN.Framework.Async;
using YonYou.U8.IN.Framework.Events;
using YonYou.U8.IN.Framework.Views;
using YonYou.U8.IN.Model;
using YonYou.U8.IN.Utility;

namespace YonYou.U8.IN.Framework.Views
{
	public class ToolBarView : AbstractView
	{
        private MetroToolBar _ToolBar;
        private Hashtable _ItemCache;
        private ObjectTable<NetLoader> _LoaderTbl;
        private AsyncWorker AsyncWorker;
        private AsyncWorkerEventArgs gloab_e;

        public ToolBarView()
		{
		}

		public ToolBarView(MetroToolBar toolBar) : this()
		{
			if (toolBar == null)
			{
				throw new ArgumentNullException("toolBar");
			}
			this._ToolBar = toolBar;
			this._ItemCache = new Hashtable();
			this._LoaderTbl = new ObjectTable<NetLoader>();
			this._ToolBar.EventSelectedItemChanging += this.SelectedItemChanging;
			this.AsyncWorker = new AsyncWorker(ViewAdvisor.Instance.MainForm);
		}

		public override Control Control
		{
			get
			{
				return this._ToolBar;
			}
		}

		internal Hashtable ItemCache
		{
			get
			{
				return this._ItemCache;
			}
		}

		protected override T InternalExecuteAction<T>(IViewAction Action, params object[] args)
		{
			T result;
			if (args != null)
			{
				object[] array = new object[args.Count<object>() + 1];
				array[0] = this;
				for (int i = 1; i <= args.Length; i++)
				{
					array[i] = args[i - 1];
				}
				result = (T)((object)Action.Execute(array));
			}
			else
			{
				result = (T)((object)Action.Execute(new object[]
				{
					this
				}));
			}
			return result;
		}

		protected override void InitializeActionTypes()
		{
            RegisteActionType<ToolBarInitialize>();
		}

		internal void OnSelectingItem()
		{
			int selectedIndex = this._ToolBar.SelectedIndex;
			if (selectedIndex >= 0)
			{
				SelectedItemEventArgs e = new SelectedItemEventArgs(this._ToolBar.SelectedItem, selectedIndex);
				this.SelectedItemChanging(this._ToolBar, e);
			}
		}

		private void SelectedItemChanging(object sender, SelectedItemEventArgs e)
		{
			try
			{
				BizMenuNode bizMenuNode = e.SelectedItem.Tag as BizMenuNode;
				e.Cancel = true;
				if (bizMenuNode != null)
				{
					CancelEventArgs cancelEventArgs = new CancelEventArgs();
					ViewAdvisor.Instance.OnPageSwitching(cancelEventArgs);
					if (!cancelEventArgs.Cancel)
					{
						this.gloab_e = null;
						BizMenu data = bizMenuNode.Data;
						this.AsyncWorker.AsynWork += this.Load_AsynWork;
						this.AsyncWorker.AsynComplete += this.Load_AsynComplete;
						this.AsyncWorker.AsynReport += this.Load_AsynReport;
						Loading loaderForm = new Loading(data.Name);
						this.AsyncWorker.LoaderForm = loaderForm;
						this.AsyncWorker.Start(e);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.WriteLine("[实施导航]-[ToolBarView->SelectedItemChanging]-[StackTrace:{0}]-[Message:{1}]", new object[]
				{
					ex.StackTrace,
					ex.Message
				});
			}
		}

		private void loader_OpenEmbedControl(object sender, NetLoaderEventArgs e)
		{
			(e.Loader as NetLoader).IsInternalEmbed = true;
			this.gloab_e.Tag = e;
			this.AsyncWorker.Report(this.gloab_e);
		}

		private void Load_AsynComplete(object sender, AsyncWorkerEventArgs e)
		{
			this.AsyncWorker.AsynWork -= this.Load_AsynWork;
			this.AsyncWorker.AsynReport -= this.Load_AsynReport;
			this.AsyncWorker.AsynComplete -= this.Load_AsynComplete;
		}

		private void Load_AsynWork(object sender, AsyncWorkerEventArgs e)
		{
			try
			{
				this.gloab_e = e;
				SelectedItemEventArgs selectedItemEventArgs = e.Argument as SelectedItemEventArgs;
				BizMenuNode bizMenuNode = selectedItemEventArgs.SelectedItem.Tag as BizMenuNode;
				BizMenu data = bizMenuNode.Data;
				if (data.ComponentType == ComponentType.Dll)
				{
					if (this._LoaderTbl.ContainsKey(data.Id))
					{
						NetLoader netLoader = this._LoaderTbl[data.Id];
						netLoader.Load(ViewAdvisor.Instance.Context, data.Id, "");
						selectedItemEventArgs.Cancel = !netLoader.IsInternalEmbed;
					}
					else
					{
						string assemblyFile = Path.Combine(PathUtils.INPath, data.Assembly);
						Assembly assembly = Assembly.LoadFrom(assemblyFile);
						if (assembly != null)
						{
							NetLoader netLoader = assembly.CreateInstance(data.Class) as NetLoader;
							if (netLoader != null)
							{
								this._LoaderTbl.Add(data.Id, netLoader);
								netLoader.OpenEmbedControl += this.loader_OpenEmbedControl;
								netLoader.Load(ViewAdvisor.Instance.Context, data.Id, "");
								selectedItemEventArgs.Cancel = !netLoader.IsInternalEmbed;
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				Debug.WriteLine("[实施导航]-[ToolBarView->SelectedItemChanging]-[StackTrace:{0}]-[Message:{1}]", new object[]
				{
					ex.StackTrace,
					ex.Message
				});
			}
			e.State = WorkerState.Completed;
		}

		private void Load_AsynReport(object sender, AsyncWorkerEventArgs e)
		{
			NetLoaderEventArgs netLoaderEventArgs = e.Tag as NetLoaderEventArgs;
			if (netLoaderEventArgs != null)
			{
				Application.DoEvents();
				INetControl control = netLoaderEventArgs.Control;
				ViewAdvisor.Instance.ClearEvents();
				BizContext con =  ViewAdvisor.Instance.Context;
				Control control2 = control.CreateControl(con);
				Application.DoEvents();
				if (control2 != null)
				{
					if (control2 is Form)
					{
						(control2 as Form).TopLevel = false;
						(control2 as Form).FormBorderStyle = FormBorderStyle.None;
						(control2 as Form).Dock = DockStyle.Fill;
						(control2 as Form).Visible = true;
						(control2 as Form).Tag = this;
						(control2 as Form).AutoScroll = true;
					}
					else
					{
						control2.Dock = DockStyle.Fill;
						control2.Visible = true;
						control2.Tag = this;
					}
					Application.DoEvents();
					ViewAdvisor.Instance.OpenEditor(control2);
					Application.DoEvents();
				}
				ViewAdvisor.Instance.QueryView<LayoutView>().StatusContainer.Visible = control.ShowStatusBar;
				Application.DoEvents();
			}
		}


	}
}